<?php
/**
 * rbac后台权限控制
 * Created by yd
 * User: xiaojun.lan
 * Date: 2018/5/29
 * Time: 11:16
 */

namespace app\api\controller;

use app\api\model\Access;
use app\api\model\Admin;
use app\api\model\AdminRole;
use app\api\model\Role;
use app\api\model\RoleAccess;
use think\Controller;
use think\Config;
use think\Db;
use think\Exception;
use think\Request;
use think\Session;

class Rbac extends Controller
{

    protected $auth_session_name = 'sw_name_99';
    protected $current_user = ''; // 当前登录用户信息
    protected $currentPage = 1; // 当前页数
    protected $pageSize = 20; // 每页行数
    protected $superAdminId = 1; // 初始化超级管理员id，限定为admin表的第一行，id为1
    protected $dbPrefix = '';

    // 未登录允许访问的控制器
    protected $allowUrl = [
        'admin/index/login',
        'api/rbac/adminLogin',
    ];

    public function _initialize()
    {
        // 设置返回数据格式，默认json格式
        $type = input('type');
        if (!in_array($type, ['json', 'xml', 'jsonp'])) {
            $type = 'json';
        }
        Config::set('default_return_type', $type);
        $this->current_user = Utils::getAdminInfo();
        $this->dbPrefix = Config::get('database.prefix');

    }

    /**
     * 检查是否是超级管理员，且是否已经登录
     * @return bool 是已登录的超级管理员
     */
    public function isAdmin(){
      /*if(Utils::isXss()){
           return false;
       }*/
        return Utils::isCsrf() || !$this->current_user || !@$this->current_user['is_admin'] || !$this->checkAdminLoginStatus() ? false : true;
    }

    /////////////////////管理员管理 start//////////////////////////////
    /**
     * 超级管理员登录后，可以分配其它管理员
     */
    public function adminRegister()
    {

        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }


        $name = input('name');
        $email = input('email');
        $password = input('password');
        $phone = input('phone');
        $mobile = input('mobile');
        $sex = input('sex');
        $isAdmin = input('is_admin');
        $status = input('status');
        $comment = input('comment');

        if(!$name){
            return Utils::arrayFormat([],6666,'用户名不能为空');
        }
        if(!$email){
            return Utils::arrayFormat([],6666,'邮箱不能为空');
        }

       /* $name = 'yd14';
        $password = '123456asd';
        $email = 'yd14@s-ec.com';
        $phone = '0778-6696658';
        $mobile = '18818881888';
        $sex = '女';
        $isAdmin = '是';
        $status = '启用';
        $comment = '冗余行';*/

        $superAdmin = array(
            'name' => $name,
            'password' => $password,
            'email' => $email,
            'phone' => $phone,
            'mobile' => $mobile,
            'sex' => $sex,
            'is_admin' => $isAdmin,
            'status' => 1,// $status // 这个字段暂时不用
            'comment' => $comment
        );
        $admin = new Admin();

        try{
            $nameData = $admin->where('name','eq',$name)->select();
            if(count($nameData) > 0){
                return Utils::arrayFormat([],3002,'用户名已经存在');
            }
        }catch (Exception $e){
            return Utils::arrayFormat([],80061,'执行查询错误');
        }

        try{
            $emailData = $admin->where('email','eq',$email)->select();
            if(count($emailData) > 0){
                return Utils::arrayFormat([],3003,'邮箱已经存在');
            }
        }catch (Exception $e){
            return Utils::arrayFormat([],80062,'执行查询错误');
        }

        if(!preg_match('|\S{6,32}|',$password)) {
            return Utils::arrayFormat([],3004,'密码组成：字母，数字，下划线组成的6-32个字符');
        }


        $res = $admin
            ->allowField(true)// 允许自动过滤字段,为数组时,只添加数组中的字段
            ->save($superAdmin);
        if($res === false){
            return Utils::arrayFormat([],80063,'数据插入错误');
        }

        return Utils::arrayFormat($superAdmin, $res);

    }

    /**
     * 后台管理员登录
     *
     */
    public function adminLogin()
    {

        $name = input('name');
        $password = input('password');
        $captcha = input('captcha');

         if(!$captcha || !captcha_check($captcha)){
             return Utils::arrayFormat([],3005,'验证码不正确'.$captcha);
         };
        if (!$name) {
            return Utils::arrayFormat([], 3006, '用户名或邮箱不能为空');
        }

        try {
            $db = new Admin();
            $adminInfo = $db->where('name', $name)->whereOr('email', $name)->select();
            if (count($adminInfo) > 1) {
                return Utils::arrayFormat([], 80001, '账号异常');
            }
            if (!$adminInfo) {
                return Utils::arrayFormat([], 80002, '账号不存在');
            }
            $adminInfo = $adminInfo[0]; // 取出二维数组中的一维数组
            $adminRole = Db::name('admin_role')// 获取管理员对应的角色名称
            ->alias('a')
                ->join('role r', 'a.role_id = r.id')
                ->field('r.name role_name,r.id role_id')  // status 字段暂时不用
                ->where('a.admin_id', 'eq', $adminInfo['id'])
                ->select();
        } catch (Exception $e) {
            return Utils::arrayFormat([], 80004, '数据库操作异常' . $e);
        }
        try {
            $adminRoleLength = count($adminRole);
            $adminInfo['role_name'] = $adminRoleLength > 0 ? $adminRole[0]['role_name'] : '';
            $adminInfo['role_id'] = $adminRoleLength > 0 ? $adminRole[0]['role_id'] : '';
            if (md5($password) != $adminInfo['password']) {
                return Utils::arrayFormat([], 80003, '账号或密码不正确');
            }
            // cookie保存用户的登录态,所以cookie值需要加密，规则：user_auth_token + "#" + uid
            $this->createLoginStatus($adminInfo);
            Utils::setAdminInfo($adminInfo);
            return Utils::arrayFormat(Utils::getAdminInfo());
        } catch (Exception $e) {
            return Utils::arrayFormat([], 80105, '数组索引异常');
        }

    }

    /**
     * 管理员退出登录
     */
    public function adminLogout()
    {

        $this->current_user = [];
        Session::clear(Config::get('session.prefix'));
        return Utils::arrayFormat([]);

    }

    /**
     * 删除管理员
     * @return array
     */
    public function adminDelete(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = input('id');
        if(!$id){
            return Utils::arrayFormat([],80064,'管理员id不能为空');
        }
        $idArr = explode(',',trim($id,','));
        if(in_array($this->superAdminId,$idArr)){
            return Utils::arrayFormat([],80091,'无法删除超级管理员');
        }

        try{
            // 检查id对应数据是否存在
            $admin = new Admin();
            $adminData = $admin->where('id','in',$idArr)->select();
            $selectIdArr = [];
            $adminDataLength = count($adminData);
            for ($j=0;$j<$adminDataLength;$j++){
                $selectIdArr[] = $adminData[$j]['id'];
            }
            $notExsitId = implode(',',array_diff($idArr,$selectIdArr));
            if($adminDataLength != count($idArr)){
                return Utils::arrayFormat([],3008,'对应管理员id['.$notExsitId.']不存在');
            }
            $deleteAdmin = Db::name('admin')->where('id','in',$idArr)->delete();
            if(!$deleteAdmin){
                return Utils::arrayFormat([],80065,'删除管理员失败');
            }
            $this->deleteAdminRoleOrder($idArr,'admin');
            return Utils::arrayFormat([]);
        }catch (Exception $e){
            return Utils::arrayFormat([],80066,'删除管理员异常');
        }
    }

    /**
     * 获取当前管理员信息
     * @return array
     */
    public function adminInfo(){
        if(!$this->checkAdminLoginStatus()){
            return Utils::arrayFormat([],2003,'没有访问权限');
        }
        return Utils::arrayFormat([Utils::getAdminInfo()]);
    }

    /**
     * 展示管理员列表
     * @return array
     */
    public function showAdminList(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        try{
            $currentPage = input('current_page');  // 当前页数
            $pageSize = input('page_size'); // 每页行数

            $currentPage = $currentPage ? $currentPage : $this->currentPage;
            $pageSize = $pageSize ? $pageSize : $this->pageSize;

            $role = Db::name('admin');
            $data =$role->alias('a')
                    // count(a.id) as admin_num
                ->field('a.id,a.comment,a.name,a.email,a.phone,a.mobile,a.sex,a.is_admin,a.status,
                a.create_time,a.update_time,IFNULL(a.delete_time,"") as delete_time,IFNULL(c.name,"") 
                as role_name,IFNULL(c.id,"") as role_id')
                ->join('admin_role b','a.id=b.admin_id','left')
                ->join('role c','b.role_id=c.id','left')
                ->order('a.id DESC')
                ->page($currentPage, $pageSize)
                ->select();

            $totalRecord = Db::query("select count(*) from ".$this->dbPrefix."admin ");
            return Utils::arrayListFormat($data,$totalRecord[0]['count(*)']);
        }catch (Exception $e){
            return Utils::arrayFormat([],80092,'获取管理员列表失败'.$e);
        }

    }

    /**
     * 更改管理员信息
     * 不需要超级管理员权限，只要登录就能操作，当前用户只能修改当前用户信息，超级管理员能修改所有管理员的信息
     * @return array
     */
    public function updateAdminInfo()
    {

        if(!$this->checkAdminLoginStatus()){
            return Utils::arrayFormat([],2001,'用户未登录');
        }
        $id = input('id');
        $email = input('email');
        $phone = input('phone');
        $mobile = input('mobile');
        $sex = input('sex');
        $isAdmin = input('is_admin');
        $status = input('status');
        $comment = input('comment');

        $adminInfo = array(
            'email' => $email,
            'phone' => $phone,
            'mobile' => $mobile,
            'sex' => $sex,
            'status' => 1,//$status //是否有效，这个字段暂时不用
            'comment' => $comment
        );

        $loginAdminId = Utils::getAdminId();
        $id = (int)$id ? $id : $loginAdminId;
        if(Utils::getAdminInfo()['is_admin'] == 1){ // 超级管理员，可以修改任何管理员的信息
            $adminInfo['is_admin'] = $isAdmin;
            $update = $this->updateAdminInfoUtil($adminInfo,$id);
        }else{
            if($id != $loginAdminId){ // 非超级管理员，只能修改自己的信息
                return Utils::arrayFormat([],80093,'没有权限修改其它管理员信息');
            }
            $update = $this->updateAdminInfoUtil($adminInfo,$id);
        }

        if($update){
            return Utils::arrayFormat([]);
        }
        return Utils::arrayFormat([],80094,'修改失败');
    }

    /**
     * 重置管理员密码
     * 只有超级管理员才能操作
     * @return array
     */
    public function resetAdminPassWord()
    {

        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }

        $name = input('name');
        $password = input('password');
        if(!$name){
            return Utils::arrayFormat([],80096,'需要修改的用户名不能为空');
        }
        if(!preg_match('|\S{6,32}|',$password)) {
            return Utils::arrayFormat([],3004,'密码组成：字母，数字，下划线组成的6-32个字符');
        }

        $adminInfo = array(
            'password' => $password,
        );

        try{
            $admin = new Admin();
            $update = $admin->save($adminInfo, function ($query) use ($name) {
                $query->where('name', 'eq', $name);
            });
            if($update !== false){
                return Utils::arrayFormat([]);
            }
        }catch (Exception $e){

        }
        return Utils::arrayFormat([],80095,'重置失败');
    }

    /**
     * 修改管理员密码，只能修改当前管理员的密码
     * @return array
     */
    public function updateAdminPassWord()
    {

        if(!$this->checkAdminLoginStatus()){
            return Utils::arrayFormat([],2001,'用户未登录');
        }

        $oldPassword = input('old_password');
        $newPassword = input('new_password');

        if(!preg_match('|\S{6,32}|',$newPassword)) {
            return Utils::arrayFormat([],3004,'密码组成：字母，数字，下划线组成的6-32个字符');
        }

        $adminInfo = array(
            'password' => $newPassword,
        );

        try{
            $id = Utils::getAdminId();
            $admin = new Admin();
            $data = $admin->get(function ($query) use ($oldPassword,$id){
                $query->where('password','eq',$oldPassword)->where('id','eq',$id);
            });
            if($data){
                $update = $admin->save($adminInfo, function ($query) use ($id) {
                    $query->where('id', 'eq', $id);
                });
                if($update !== false){
                    return Utils::arrayFormat([]);
                }
            }
            return Utils::arrayFormat([],80097,'修改密码失败，请确认旧密码输入是否正确');
        }catch (Exception $e){
            return Utils::arrayFormat([],80098,'修改密码失败，服务器异常');
        }

    }

    private function updateAdminInfoUtil($adminInfo,$id){
        try{
            $admin = new Admin();
            $update = $admin->save($adminInfo, function ($query) use ($id) {
                $query->where('id', 'eq', $id);
            });
            if($update !== false){
                return true;
            }
            return false;
        }catch (Exception $e){
            return false;
        }

    }

    /////////////////////管理员管理 end  //////////////////////////////



    /////////////////////角色管理 start//////////////////////////////
    /**
     * 增加或编辑角色
     * @return array
     */
    public function editRole()
    {
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        
        $roleId = (int)input('id');
        $roleName = input('name');
        $roleStatus = input('status');
        $comment = input('comment');

        if(empty($roleName)){
            return Utils::arrayFormat([],80009,'角色名称不能为空');
        }

        $roleArr = array(
            'name'   => $roleName,
            'status' => 1,//$roleStatus, // 默认有效1，暂时不用这个字段
            'comment' => $comment
        );

        $role = new Role();
        if ($roleId > 0) {
            try{
                // 修改角色表
                $update = $role->save($roleArr, function ($query) use ($roleId) {
                    $query->where('id', 'eq', $roleId);
                });
                if($update !== false){
                    return Utils::arrayFormat($roleArr);
                }
            }catch (Exception $e){

            }
            return Utils::arrayFormat([],80005,'角色更改失败');
        } else {
            try{
                $data = Role::get(function ($query) use ($roleName){
                    $query->where('name','eq',$roleName);
                });
                if($data){
                    return Utils::arrayFormat($data,3007,'该角色名已经存在');
                }
                // 增加角色
                $add = $role->allowField(true)->save($roleArr);
                if($add){
                    return Utils::arrayFormat($roleArr);
                }
            }catch (Exception $e){

            }
            return Utils::arrayFormat([],80006,'角色添加失败');
        }

    }

    /**
     * 根据角色id删除角色
     * @return array
     */
    public function deleteRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = input('id');
        if(!$id){
            return Utils::arrayFormat([],80012,'角色id不能为空');
        }
        $idArr = explode(',',trim($id,','));
        try{
            // 检查id对应数据是否存在
            $role = new Role();
            $selectData = $role->where('id','in',$idArr)->select();
            $selectIdArr = [];
            $selectDataLength = count($selectData);
            for ($j=0;$j<$selectDataLength;$j++){
                $selectIdArr[] = $selectData[$j]['id'];
            }
            $notExsitId = implode(',',array_diff($idArr,$selectIdArr));
            if($selectDataLength != count($idArr)){
                return Utils::arrayFormat([],80099,'对应角色id['.$notExsitId.']不存在');
            }

            $result = Db::name('role')->where('id','in',$idArr)->delete();
            if($result){
                $this->deleteAdminRoleOrder($idArr,'role'); // 删除管理员-角色关系表中对应数据
                $this->deleteRoleAccessOrder($idArr); // 删除角色id在管理员-角色关系表中对应的数据
                return Utils::arrayFormat([]);
            }else{
                return Utils::arrayFormat([],80011,'没有删除任何数据');
            }
        }catch (Exception $e){
            return Utils::arrayFormat([],80010,'数据库操作异常');
        }

    }

    /**
     * 展示角色列表
     * @return array
     */
    public function showRoleList(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        try{
            $currentPage = input('current_page');  // 当前页数
            $pageSize = input('page_size'); // 每页行数

            $currentPage = $currentPage ? $currentPage : $this->currentPage;
            $pageSize = $pageSize ? $pageSize : $this->pageSize;

            $role = Db::name('role');
            $data = $role
                ->alias('a')
                ->field('a.id,a.name,a.status,IFNULL(a.comment,"") as comment,a.create_time,
                IFNULL(a.update_time,0) as update_time,IFNULL(a.delete_time,0) AS delete_time,
                c.title as access_title,c.urls as access_urls,c.id as access_id')
                ->join('role_access b','a.id=b.role_id','left')
                ->join('access c','find_in_set(c.id,b.access_id)','left')
                ->order('id DESC')
                ->page($currentPage, $pageSize)
                ->select();

            $data = $this->groupRoleLisetArr($data);
            $totalRecord = Db::query("select count(*) from ".$this->dbPrefix."role ");
            return Utils::arrayListFormat($data,$totalRecord[0]['count(*)']);
        }catch (Exception $e){
            return Utils::arrayFormat([],80007,'获取角色列表失败'.$e);
        }

    }

    /**
     * 抽取一维数组中相同值中不同值为二维数组返回
     * @param $arr
     * @return array
     */
    private function groupRoleLisetArr($arr){
        if(!is_array($arr)){
            $arr = json_decode($arr,true);
        }
        $arrLength = count($arr);
        if ($arrLength < 1){
            return [];
        }
        $roleArr = $arr;
        $accessArr = $arr;
        foreach ($roleArr as $k => $v){
            unset($accessArr[$k]['id']);
            unset($accessArr[$k]['name']);
            unset($accessArr[$k]['status']);
            unset($accessArr[$k]['comment']);
            unset($accessArr[$k]['create_time']);
            unset($accessArr[$k]['update_time']);
            unset($accessArr[$k]['delete_time']);

            unset($roleArr[$k]['access_title']);
            unset($roleArr[$k]['access_urls']);
            unset($roleArr[$k]['access_id']);

        }

        $group = array_values(array_unique($roleArr,SORT_REGULAR));

        $groupLength = count($group);
        for($i=0;$i<$arrLength;$i++){
            $arrArrId = $arr[$i]['id'];
            for($j=0;$j<$groupLength;$j++){
                $groupId = $group[$j]['id'];
                if($arrArrId == $groupId){
                    if($accessArr[$j]['access_title']){
                        $group[$j]['access'][] = $accessArr[$i];
                    }else{
                        $group[$j]['access'] = [];
                    }

                }
            }
        }

        return $group;
    }

    /**
     * 根据id查询角色
     * @return array
     */
    public function findRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $roleId = (int)input('id');
        $roleId = 1;
        try{
            $role = Db::name('role');
            $data = $role
                ->alias('a')
                ->field('a.id,a.name,a.status,IFNULL(a.comment,"") as comment,a.create_time,
                IFNULL(a.update_time,0) as update_time,IFNULL(a.delete_time,0) AS delete_time,
                IFNULL(c.id,"") as admin_id,IFNULL(c.name,"") as admin_name,
                IFNULL(c.is_admin,"") as is_admin,IFNULL(c.comment,"") as admin_comment')
                ->join('admin_role b','a.id=b.role_id','left')
                ->join('admin c','c.id = b.admin_id','left')
                ->where('a.id','eq',$roleId)
                ->order('id DESC')
                ->select();

            $data = $this->groupRolerWithAdminArr($data);
            return Utils::arrayFormat($data);
        }catch (Exception $e){
            return Utils::arrayFormat([],80008,'获取角色信息失败');
        }

    }

    /**
     * 抽取一维数组中相同值中不同值为二维数组返回
     * @param $arr
     * @return array
     */
    private function groupRolerWithAdminArr($arr){
        if(!is_array($arr)){
            $arr = json_decode($arr,true);
        }
        $arrLength = count($arr);
        if ($arrLength < 1){
            return [];
        }
        $roleArr = $arr;
        $adminArr = $arr;
        foreach ($roleArr as $k => $v){
            unset($adminArr[$k]['id']);
            unset($adminArr[$k]['name']);
            unset($adminArr[$k]['status']);
            unset($adminArr[$k]['comment']);
            unset($adminArr[$k]['create_time']);
            unset($adminArr[$k]['update_time']);
            unset($adminArr[$k]['delete_time']);

            unset($roleArr[$k]['admin_id']);
            unset($roleArr[$k]['admin_name']);
            unset($roleArr[$k]['admin_comment']);

        }

        $group = array_values(array_unique($roleArr,SORT_REGULAR));

        $groupLength = count($group);
        for($i=0;$i<$arrLength;$i++){
            $arrArrId = $arr[$i]['id'];
            for($j=0;$j<$groupLength;$j++){
                $groupId = $group[$j]['id'];
                if($arrArrId == $groupId){
                    if($adminArr[$i]['admin_id']){
                        $group[$j]['admin'][] = $adminArr[$i];
                    }else{
                        $group[$j]['admin'] = [];
                    }
                }
            }
        }

        return $group;
    }

    /**
     * 根据role_id查询角色对应的权限列表
     * @return array
     */
    public function roleHaveAccessList(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $roleId = (int)input('id');
        try{
            $role = Db::name('role');
            $data = $role
                ->alias('a')
                ->field('a.id,a.name,a.status,IFNULL(a.comment,"") as comment,a.create_time,
                IFNULL(a.update_time,0) as update_time,IFNULL(a.delete_time,0) AS delete_time,
                c.title as access_title,c.urls as access_urls,c.id as access_id,IFNULL(c.comment,"") as comment')
                ->join('role_access b','a.id=b.role_id','left')
                ->join('access c','find_in_set(c.id,b.access_id)','left')
                ->where('a.id','eq',$roleId)
                ->order('id DESC')
                ->select();

            $data = $this->groupRolerWithAccessArr($data);
            return Utils::arrayFormat($data);
        }catch (Exception $e){
            return Utils::arrayFormat([],80008,'获取角色信息失败');
        }

    }

    /**
     * 抽取一维数组中相同值中不同值为二维数组返回
     * @param $arr
     * @return array
     */
    private function groupRolerWithAccessArr($arr){
        if(!is_array($arr)){
            $arr = json_decode($arr,true);
        }
        $arrLength = count($arr);
        if ($arrLength < 1){
            return [];
        }
        $roleArr = $arr;
        $adminArr = $arr;
        foreach ($roleArr as $k => $v){
            unset($adminArr[$k]['id']);
            unset($adminArr[$k]['name']);
            unset($adminArr[$k]['status']);
            unset($adminArr[$k]['comment']);
            unset($adminArr[$k]['create_time']);
            unset($adminArr[$k]['update_time']);
            unset($adminArr[$k]['delete_time']);

            unset($roleArr[$k]['access_id']);
            unset($roleArr[$k]['access_title']);
            unset($roleArr[$k]['access_urls']);
            unset($roleArr[$k]['access_comment']);

        }

        $group = array_values(array_unique($roleArr,SORT_REGULAR));

        $groupLength = count($group);
        for($i=0;$i<$arrLength;$i++){
            $arrArrId = $arr[$i]['id'];
            for($j=0;$j<$groupLength;$j++){
                $groupId = $group[$j]['id'];
                if($arrArrId == $groupId){
                    if($adminArr[$i]['access_id']){
                        $group[$j]['access'][] = $adminArr[$i];
                    }else{
                        $group[$j]['access'] = [];
                    }
                }
            }
        }

        return $group;
    }


    /////////////////////角色管理 end//////////////////////////////




    /////////////////////管理员-角色管理 start//////////////////////////////
    /**
     * 增加管理员-角色关系
     * @return array
     */
    public function addAdminRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $admin_id = (int)input('admin_id');
        $role_id = (int)input('role_id');
        if(!$admin_id){
            return Utils::arrayFormat([],80019,'管理员admin_id不能为空');
        }
        if(!$role_id){
            return Utils::arrayFormat([],80020,'角色role_id不能为空');
        }
        $adminRoleArr = array(
          'admin_id' => $admin_id,
          'role_id'  => $role_id
        );
        try{
            $adminRole = new AdminRole();
            $data = $adminRole->all(function ($query) use ($admin_id){
                $query->where('admin_id','eq',$admin_id);
            });
            if(count($data) > 0){
                return Utils::arrayFormat($data,80025,'该管理员已经存在对应角色关系');
            }
            $addRes = $adminRole->allowField(true)->save($adminRoleArr);
            if($addRes){
               return Utils::arrayFormat([]);
            }
        }catch (Exception $e){

        }
       return Utils::arrayFormat([],80021,'增加管理员、角色关系失败');

    }

    /**
     * 根据管理员id（admin_id）删除管理员-角色关系
     * @return array
     */
    public function deleteAdminRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = input('id');
        if (!$id) {
            return Utils::arrayFormat([], 80014, 'id不能为空');
        }
        $idArr = explode(',',trim($id,','));
        try {
            // 检查id对应数据是否存在
            $adminRole = new AdminRole();
            $selectData = $adminRole->where('id','in',$idArr)->select();
            $selectIdArr = [];
            $selectDataLength = count($selectData);
            for ($j=0;$j<$selectDataLength;$j++){
                $selectIdArr[] = $selectData[$j]['id'];
            }
            $notExsitId = implode(',',array_diff($idArr,$selectIdArr));
            if($selectDataLength != count($idArr)){
                return Utils::arrayFormat([],80100,'对应管理员角色id['.$notExsitId.']不存在');
            }
            $delete = AdminRole::where('id', 'in', $idArr)->delete();
            if ($delete) {
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([], 80015, '没有删除任何数据');
        } catch (Exception $e) {
            return Utils::arrayFormat([], 80016, '数据库操作异常');
        }
    }

    /**
     * 更新管理员-角色关系
     * @return array
     */
    public function updateAdminRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = (int)input('id');
        $role_id = (int)input('role_id');
        if(!$id){
           return Utils::arrayFormat([],80022,'id不能为空');
        }
        if(!$role_id){
           return Utils::arrayFormat([],80023,'角色role_id不能为空');
        }
        $updateArr = array(
            'role_id'  => $role_id
        );
        try{
            $adminRole = new AdminRole();
            $res = $adminRole->save($updateArr,function ($query) use ($id){
                $query->where('id','eq',$id);
            });
            if($res){
              return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([],80024,'更改管理员、角色关系失败');
        }catch (Exception $e){
            return Utils::arrayFormat(['aa'=>$e],80026,'数据库操作失败');
        }

    }

    /**
     * 获取所有管理员-角色关系列表
     * @return array
     */
    public function listAdminRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        try{
            $db = new AdminRole();
            $list =$db->alias('a')
                ->join('admin b','a.admin_id = b.id')
                ->join('role c','a.role_id = c.id')
                ->field('a.id as id,b.name as admin_name,c.name as role_name,a.create_time')
                ->select();
            return Utils::arrayFormat($list);
        }catch (Exception $e){
            return Utils::arrayFormat([],80013,'管理员、角色列表获取失败');
        }
    }

    /**
     * 根据admin_id（管理员id）获取管理员和角色之间的关系
     * @return array
     */
    public function findAdminRole(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $admin_id = (int)input('admin_id');
        if(!$admin_id){
           return Utils::arrayFormat([],80017,'管理员admin_id不能为空');
        }
        try{
           /* $data = AdminRole::get(function ($query) use ($admin_id){
                $query->where('admin_id','eq',$admin_id);
            });*/
            $db = new AdminRole();
            $data =$db
                ->alias('a')
                ->join('admin b','a.admin_id = b.id')
                ->join('role c','a.role_id = c.id')
                ->field('a.id as id,b.name as admin_name,c.name as role_name,a.create_time')
                ->where('admin_id','eq',$admin_id)
                ->select();
            return Utils::arrayFormat($data);
        }catch (Exception $e){
            return Utils::arrayFormat([],80018,'数据库操作异常');
        }

    }

    /**
     * 获取用户表列表和角色表列表
     * @return array
     */
    public function getNameList(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $adminList = '';
        $roleList  = '';
        try{
            $adminList = Admin::all(function ($query){ // 方式三,使用闭包函数
                $query->where('id','>',0)->field('id,name');
            });
        }catch (Exception $e){

        }

        try{
            $roleList = Role::all(function ($query){ // 方式三,使用闭包函数
                $query->where('id','>',0)->field('id,name');
            });
        }catch (Exception $e){

        }

        return Utils::arrayFormat(
            array(
                'admin' => $adminList,
                'role'  => $roleList
            )
        );

    }
    /////////////////////管理员-角色管理 end  //////////////////////////////




    /////////////////////权限管理 start//////////////////////////////
    /**
     * 增加权限管理
     * @return array
     */
    public function addAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $title = input('title');
        $urls = input('urls');
        $comment = input('comment');
        if(!$title){
            return Utils::arrayFormat([],80027,'标题title字段值不能为空');
        }
        if(!$urls){
            return Utils::arrayFormat([],80028,'urls不能为空');
        }
        $accessArr = array(
            'title' => $title,
            'urls'  => $urls,
            'comment'  => $comment,
        );
        try {
            $access = new Access();
            $data = $access->all(function ($query) use ($title,$urls) {
                $query->where('title', 'eq', $title);
            });
            if(count($data)){
                return Utils::arrayFormat([],80029,'该标题已经存在');
            }
            $addRes = $access->allowField(true)->save($accessArr);
            if($addRes){
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([],80030,'没有插入任何数据');
        } catch (Exception $e) {
            return Utils::arrayFormat([],80031,'插入数据库异常');
        }

    }

    /**
     * 删除权限
     * @return array
     */
    public function deleteAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = input('id');
        if(!$id){
            return Utils::arrayFormat([],80032,'id不能为空');
        }
        $idArr = explode(',',trim($id,','));
        try{

            // 检查id对应数据是否存在
            $access = new Access();
            $selectData = $access->where('id','in',$idArr)->select();
            $selectIdArr = [];
            $selectDataLength = count($selectData);
            for ($j=0;$j<$selectDataLength;$j++){
                $selectIdArr[] = $selectData[$j]['id'];
            }
            $notExsitId = implode(',',array_diff($idArr,$selectIdArr));
            if($selectDataLength != count($idArr)){
                return Utils::arrayFormat([],80101,'对应权限id['.$notExsitId.']不存在');
            }

            $deleteRes = Db::name('access')->where('id','in',$idArr)->delete();
//            $deleteRes = Access::where('id','in',$idArr)->delete();
            if($deleteRes){
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([],80033,'没有删除任何数据');
        }catch (Exception $e){
            return Utils::arrayFormat([],80034,'删除操作发生错误');
        }

    }

    /**
     * 更新权限
     * @return array
     */
    public function updateAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = input('id');
        $title = input('title');
        $urls = input('urls');
        $comment = input('comment');
        if (!$id) {
            return Utils::arrayFormat([], 80035, 'id不能为空');
        }
        $arr = array(
            'title' => $title,
            'urls' => $urls,
            'comment' => $comment
        );
        try {
            $access = new Access();
            $data = $access->save($arr, function ($query) use ($id) {
                $query->where('id', 'eq', $id);
            });
            if ($data) {
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([], 80036, '没有更新任何数据');
        } catch (Exception $e) {
            return Utils::arrayFormat([], 80037, '更新数据操作异常');
        }

    }

    /**
     * 获取权限列表
     * @return array
     */
    public function listAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        try{

            $currentPage = input('current_page');  // 当前页数
            $pageSize = input('page_size'); // 每页行数

            $currentPage = $currentPage ? $currentPage : $this->currentPage;
            $pageSize = $pageSize ? $pageSize : $this->pageSize;

            $access = Db::name('access');
            $data = $access->order('id DESC')
                ->page($currentPage, $pageSize)
                ->select();
            $totalRecord = Db::query("select count(*) from ".$this->dbPrefix."access ");
            return Utils::arrayListFormat($data,$totalRecord[0]['count(*)']);

          /*  $access = new Access();
            $data = $access->select();
            if($data){
                return Utils::arrayFormat($data);
            }*/
        }catch (Exception $e){
            return Utils::arrayFormat([],80038,'数据库操作异常');
        }

    }
    /////////////////////权限管理 end  //////////////////////////////


    /////////////////////角色-权限管理 start//////////////////////////
    /**
     * 插入角色-权限列表
     * @return array
     */
    public function addRoleAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $roleId = (int)input('role_id');
        $accessIdList = trim(input('access_id_list')); //  权限id列表，id之间使用逗号分隔，首尾无逗号
        if(!$roleId){
            return Utils::arrayFormat([],80039,'权限role_id不能为空');
        }
        if(!$accessIdList){
            return Utils::arrayFormat([],80040,'权限access_id_list列表不能为空');
        }
        if(!$this->checkAccessIdList($accessIdList)){
            return Utils::arrayFormat([],80041,'权限列表access_id_list格式错误');
        }
        $roleAccessArr = array(
            'role_id' => $roleId,
            'access_id'=> $accessIdList
        );
        try{
            $roleAccess = new RoleAccess();
            $data = $roleAccess->all(function ($query) use ($roleId){
                $query->where('role_id','eq',$roleId);
            });
            if(count($data) > 0){
                return Utils::arrayFormat([],80042,'该角色对应权限列表已经存在');
            }
            $add = $roleAccess->allowField(true)->save($roleAccessArr);
            if($add){
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([],80043,'没有插入任何数据');
        }catch (Exception $e){
            return Utils::arrayFormat([],80044,'插入角色对应权限列表错误');
        }
    }

    /**
     * 删除角色-权限列表
     * @return array
     */
    public function deleteRoleAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = input('id');
        if(!$id){
            return Utils::arrayFormat([],80045,'角色-权限列表id不能为空');
        }
        $idArr = explode(',',trim($id,','));
        try{
            // 检查id对应数据是否存在
            $roleAccess = new RoleAccess();
            $selectData = $roleAccess->where('id','in',$idArr)->select();
            $selectIdArr = [];
            $selectDataLength = count($selectData);
            for ($j=0;$j<$selectDataLength;$j++){
                $selectIdArr[] = $selectData[$j]['id'];
            }
            $notExsitId = implode(',',array_diff($idArr,$selectIdArr));
            if($selectDataLength != count($idArr)){
                return Utils::arrayFormat([],80102,'对应权限角色id['.$notExsitId.']不存在');
            }

            $delete = RoleAccess::where('id','in',$id)->delete();
            if($delete){
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([],80046,'没有删除任何数据');
        }catch (Exception $e){
            return Utils::arrayFormat([],80047,'删除数据失败');
        }

    }

    /**
     * 更新角色-权限列表
     * @return array
     */
    public function updateRoleAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = (int)input('id');
        $accessIdList = input('access_id');
        if(!$id){
            return Utils::arrayFormat([],80048,'角色-权限id不能为空');
        }
        if(!$this->checkAccessIdList($accessIdList)){
            return Utils::arrayFormat([],80049,'权限access_id列表格式不正确');
        }
        try{
            $roleAccess = new RoleAccess();
            $add = $roleAccess->save(array('access_id'=>$accessIdList),function ($query) use ($id){
                $query->where('id','eq',$id);
            });
            if($add){
                return Utils::arrayFormat([]);
            }
            return Utils::arrayFormat([],80050,'没有更新任何数据');
        }catch (Exception $e){
            return Utils::arrayFormat([],80051,'更新数据错误');
        }
    }

    /**
     * 根据id或者role_id获取一条对应角色-权限
     * @return array
     */
    public function findRoleAccess(){
        if(!$this->isAdmin()){
            return Utils::arrayFormat([],2002,'只有超级管理员才能访问该界面');
        }
        $id = (int)input('id');
        $role_id = (int)input('role_id');
        if(!$id && !$role_id){
            return Utils::arrayFormat([],80053,'需要角色-权限id或者角色role_id');
        }
        try{
            // SElect A.id,A.`name`,B.a_id from sw_a A
            // LEFT JOIN sw_b B on FIND_IN_SET(A.id,B.a_id)
            // where B.id>0 and B.id=4;
            /*$prefix = Config::get('prefix');
            $data = Db::query("select a.id,a.`name`,b.access_id from ".$prefix."role_access a
             left join ".$prefix."access b on FIND_IN_SET(a.id,b.access_id)
             where b.id>0 and b.id=".$id);*/

            $roleAccess = new RoleAccess();
            if($id > 0){
                $data = $roleAccess->get(function ($query) use ($id){
                    $query->where('id','eq',$id);
                });
            }else{
                $data = $roleAccess->get(function ($query) use ($role_id){
                    $query->where('role_id','eq',$role_id);
                });
            }
            if($data !== false){
                return Utils::arrayFormat($data);
            }
            return Utils::arrayFormat($data,80052,'查询失败');
        }catch (Exception $e){
            return Utils::arrayFormat([],80054,'查询数据操作失败');
        }

    }
    /////////////////////角色-权限管理 end  //////////////////////////


    public function test(){
        if($this->checkAllowVisit()){
            return Utils::arrayFormat([['msg'=>'允许访问']]);
        }
        return Utils::arrayFormat([['msg'=>'不允许访问']]);
    }


    /////////////////////check visit 方法 start///////////////////////
    /**
     * 检查当前用户是否有权限访问当前页面
     * @return bool false:提示去登录或无权限访问；true:提示可以访问
     */
    public function checkAllowVisit()
    {

        if ($this->checkAccessPage() && $this->checkAdminLoginStatus()) {
            return true;
        }
        return false;

    }

    /**
     * 检查当前用户是否有访问权限
     * @return bool | array
     */
    protected function checkAccessPage()
    {

        //如果是超级管理员 也不需要权限判断
        if($this->isAdmin()){
            return true;
        }

        $request = Request();

        // 有一些页面是不需要进行权限判断的
        $module = $request->module();
        $controller = $request->controller();
        $action = $request->action();
        $url = $module . '/' . $controller . '/' . $action;

        // 如果访问不需要登录的url，直接返回true
        if ((strlen($url) > 2) && in_array($url, $this->allowUrl)) {
            return true;
        }

        //1. 查找URL权限对应的id
        try{
            $access = new Access();
            $sUrl = json_encode($url,true);
            $accessData = $access->get(function ($query)use($sUrl){
//                $query->where('urls','like','%'.$sUrl.'%');
                $query->where('urls','eq',$sUrl);
            });
            if($accessData === false){
                return false; // 获取权限URL对应信息失败
            }
        }catch (Exception $e){
            return false; // 获取权限URL对应信息失败
        }
        if(count($accessData) < 1 || (int)@$accessData['id'] < 1){
            return false; // 该URL没有加入权限组
        }
        $adminId = @$this->current_user['id'];
        // 2. 通过管理员id查找对应角色信息
        try{
            $adminRole = new AdminRole();
            $adminRoleData = $adminRole->get(function ($query) use ($adminId){
                $query->where('admin_id','eq',$adminId);
            });
            if($adminRoleData === false){
                return false; // 获取管理员-角色对应信息失败
            }
        }catch (Exception $e){
            return false; // 获取管理员-角色对应信息失败
        }

        // 3. 通过角色role_id获取权限列表
        if(count($adminRoleData) < 1 || (int)@$adminRoleData['id'] < 1){
            return false; // 管理员对应角色信息不存在
        }
        $roleId = (int)@$adminRoleData['role_id'];
        try{
            $roleAccess = new RoleAccess();
            $roleAccessData = $roleAccess->find(function ($query) use ($roleId){
                $query->where('role_id','eq',$roleId);
            });
            if($roleAccessData === false){
                return false; // 获取角色-权限对应信息失败
            }
        }catch (Exception $e){
            return false; // 获取角色-权限对应信息失败
        }
        if(count($roleAccessData) < 1 || !@$roleAccessData['access_id']){
            return false; // 该角色没有相应任何权限
        }
        $accessIdArr = explode(',',$roleAccessData['access_id']);

        if(in_array($accessData['id'],$accessIdArr) || in_array((int)$accessData['id'],$accessIdArr)){
            return true;
        }
        return false;

    }

    /**
     * 检查是否登录
     * @return bool
     */
    public function checkAdminLoginStatus()
    {

        $auth_session = Session::get($this->auth_session_name);
        if (!$auth_session) {
            return false;
        }
        list($auth_token, $uid) = explode("#", $auth_session);

        if (!$auth_token || !$uid) {
            return false;
        }

        if ($uid && preg_match("/^\d+$/", $uid)) {
            try {
                $Db = new Admin();
                $adminInfo = $Db->where('id', $uid)->find();
                if (!$adminInfo) {
                    return false;
                }
                //校验码
                if ($auth_token != $this->createAuthToken($adminInfo['id'], $adminInfo['name'], $adminInfo['email'], $_SERVER['HTTP_USER_AGENT'])) {
                    return false;
                }
            } catch (Exception $e) {
                return false;
            }
            return true;
        }
        return false;
    }
    /////////////////////check visit 方法 end  /////////////////////////



    /////////////////////private方法 start//////////////////////////////

    private function checkAccessIdList($accessIdList){
        if(preg_match('/^[0-9\,]+$/',$accessIdList))
        {
            return true;
        }
        return false;
    }

    /**
     * 设置登录态 session
     * @param $adminInfo
     */
    private function createLoginStatus($adminInfo)
    {
        $auth_token = $this->createAuthToken($adminInfo['id'], $adminInfo['name'], $adminInfo['email'], $_SERVER['HTTP_USER_AGENT']);
        Session::set($this->auth_session_name, $auth_token . "#" . $adminInfo['id']);
    }

    /**
     * 用户相关信息生成加密校验码函数
     * @param $uid int 管理员自升id
     * @param $name string 管理员用户名
     * @param $email string 管理员邮箱
     * @param $user_agent
     * @return string
     */
    private function createAuthToken($uid, $name, $email, $user_agent)
    {
        return md5($uid . $name . $email . $user_agent);
    }
    /////////////////////private方法 end  //////////////////////////////



    //////删除用户或删除角色，就删除管理员-角色管理对应关系 start//////////
    private function deleteAdminRoleOrder($id,$type){
        if (!$id || !$type) {
            return false;
        }
        switch ($type){
            case 'admin':
                $typeId = 'admin_id';
                break;
            case 'role':
                $typeId = 'role_id';
                break;
            default:
                return false;
                break;
        }
        try {
            $delete = Db::name('admin_role')->where($typeId,'in',$id);
            if ($delete) {
                return true;
            }
            return false;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 通过权限role_id删除角色-权限对应关系数据
     * @param $roleId
     * @return bool
     */
    private function deleteRoleAccessOrder($roleId){
        if($roleId){
            return false;
        }
        try{
            $delete = Db::name('role_access')->where('role_id','in',$roleId)->delete();
            if($delete){
                return true;
            }
        }catch (Exception $e){
            return false;
        }
        return false;

    }
    //////删除用户或删除角色，就删除管理员-角色管理对应关系 end  //////////





}

